package jdbcUtils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class JdbcUtilsV5 {
    private static ThreadLocal<Connection> threadLocal;
    private static DataSource dataSource;

    //静态代码块，类加载的时候初始化赋值！
    static {
        threadLocal = new ThreadLocal<>();
        dataSource = new ComboPooledDataSource();
    }
    /**
     * 获取连接池的dataSource对象
     * @return 返回该项目唯一的连接池dataSource对象
     */
    public static DataSource getDataSource(){
        return dataSource;
    }

    /**
     * 获取Connection对象（不适合多线程）
     * @return 返回一个新的普通的Connection对象
     */
    public static Connection getNormalConnection(){
        Connection connection = null;
        try {
            if(connection == null){
                System.out.println(dataSource);
                connection = dataSource.getConnection();
            }
        } catch (SQLException e) {
            System.out.println("打印刚刚创建的connection为：" + connection);
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 获取Connection对象（适合多线程）
     * @return 返回一个Connection对象
     */
    public static Connection getThreadConnection(){
        Connection connection = threadLocal.get();
        if(connection == null){
            connection = getNormalConnection();
            threadLocal.set(connection);
        }
        return connection;
    }

    /**
     * 开启事务（适合多线程）
     */
    public static void threadConnectionStart(){
        Connection connection = threadLocal.get();
        try {
            if(connection == null){
                connection = getThreadConnection();
                connection.setAutoCommit(false);
            }else{
                System.out.println("此时connection不为空，一个线程不能一次重复开启多个事务！");
                throw new RuntimeException("一个线程不能一次重复开启多个事务！");
            }
        } catch (SQLException e) {
            System.out.println("开启事务失败！");
            e.printStackTrace();
        }
    }

    /**
     * 提交事务（适合多线程）
     */
    public static void threadConnectionCommit(){
        Connection connection = threadLocal.get();
        if(connection == null){
            throw new RuntimeException("事务并未开启，则不能进行提交！");
        }
        try {
            connection.commit();
            connection.close();
            threadLocal.remove();
        } catch (SQLException e) {
            System.out.println("提交事务失败！");
            e.printStackTrace();
        }
    }

    /**
     * 回滚事务（适合多线程）
     */
    public static void threadConnectionRollback(){
        Connection connection = threadLocal.get();
        if(connection == null){
            throw new RuntimeException("事务并未开启，则不能进行回滚！");
        }
        try {
            if(!connection.getAutoCommit()){
                connection.rollback();
                connection.close();
                threadLocal.remove();
            }
        } catch (SQLException e) {
            System.out.println("回滚事务失败！");
            e.printStackTrace();
        }
    }

}
